
#include "../include/qtwi/iapplication.hpp"
#include "../include/qtwi/core/iiapplication.hpp"

// TNW++ callback auxiliary //

// Mapping calling back widgets to IActionHandlers
std::map<TN_WIDGET*, TObjectActionHandle> TIAction::action_handler_map;
std::map<QObject*, ITimerHandler*> QITimer::timer_widget_map;

// IColor
QIColor::QIColor()
{
	// todo, more colors: Ultratronik
	mapping[Yellow] = "yellow";
	mapping[Green] = "green";
	mapping[Blue] = "blue";
	mapping[Grey] = "";
}

TIColor::TIColor()
{
	mapping[Yellow] = MWRGB(255, 255, 0);
	mapping[Green] = MWRGB(0, 128, 0);
	mapping[Blue] = MWRGB(0, 0, 128);
	mapping[Grey] = MWRGB(200, 200, 200);
}

// Timers
void QTimerActionHandler::handler(IWidget &action_parent)
{
#ifdef DEBUG
	std::cerr << "[generic timer action handler called: " <<
		&action_parent << "]" << std::endl;
#endif
	QITimer::timer_widget_map[dynamic_cast<QTimer*>(&action_parent)]->timeout();
}

extern "C" void TITimer::generic_callback(TN_WIDGET *wdg, void *data)
{
#ifdef DEBUG
	std::cerr << "[generic timer callback called]" << std::endl;
#endif
	static_cast<ITimerHandler*>(data)->timeout();
}

QIActionSignalMap::QIActionSignalMap()
{
	mapping[IAction::CLICK] = QActionWidgetMapper(SIGNAL(clicked()));
	mapping[IAction::MOD] = QActionWidgetMapper(SIGNAL(sliderMoved(int)));
	mapping[IAction::TIME] = QActionWidgetMapper(SIGNAL(timeout()));
}

/*void QIAction::generic_slot()
{

	
}*/

void QIAction::registerAction(IWidget &actionReceiver, IAction::Action action, IActionHandler *ah)
{

	QIWidget &wg = dynamic_cast<QIWidget&>(actionReceiver);	

	//
	// FIXME: What follows is probably non-portable RTTI
	//
	// We must use RTTI here because we aren't able to change Qt's class
	// hierachy which would allow us to use all kinds of nifty things like
	// like virtual inheritance, etc ... alas, we can't.
	//

#ifdef DEBUG
	std::cerr << "[type = " << std::string(tid(wg)) << "]" << std::endl;
#endif
		
	// Compare and connect if IWidget `is a' Qt object of a certain kind
		
	if ocmp_and_connect(wg, QIButton*, QPushButton*);
	else if ocmp_and_connect(wg, QIScrollbar*, QScrollBar*);
	else if ocmp_and_connect(wg, QICheckButton*, QCheckBox*);
	else if ocmp_and_connect(wg, QIRadioButton*, QRadioButton*);
	else if ocmp_and_connect(wg, QITiming*, QTimer*);
}

TIActionEventMap::TIActionEventMap()
{
		mapping[IAction::CLICK] = CLICKED;
		mapping[IAction::CLOSE] = CLOSED;
}

extern "C" void tnw_callback(TN_WIDGET *caller, void*) {
	TObjectActionHandle &handler = TIAction::action_handler_map[caller];
	TIAction::action_handler_map[caller].ah->handler(*handler.sender);
}

void TIAction::registerAction(IWidget &actionReceiver, IAction::Action action, IActionHandler *ah)
{
	TN_WIDGET *wg = *dynamic_cast<TIWidget&>(actionReceiver);
	std::pair<TN_WIDGET*, TObjectActionHandle> p(wg, TObjectActionHandle(ah, &actionReceiver));
	TIAction::action_handler_map.insert(p);
	tnRegisterCallBack(wg, event_map[action], tnw_callback, NULL);
}

// IApplication

void QIApplication::registerTimer(ITimerHandler *timerh, IWidget *parent, time_t interval)
{
	QITiming *tim = new QITiming();
	IWidget *wid = tim;
	QITimer::timer_widget_map[dynamic_cast<QTimer*>(tim)] = timerh;
	registerAction(*wid, IAction::TIME, &qtah);
	tim->start(interval);
}
